#include "flv.h"
namespace Media
{
	FLV::FLV(
		const FLVParam& flv_param,
		AVCodecContext* in_video_codec, 
		AVCodecContext* in_audio_codec):m_flv_param(flv_param), StreamMuxingBase(ENUM_STREAM_FLV,
			in_video_codec, in_audio_codec)
	{
		m_stream_url = "*.flv";
		// 转换时间的基底时间
		m_tran_time_base.num = 1;
		m_tran_time_base.den = AV_TIME_BASE;

		/*file = new File::File("222.flv");
		file->open();*/
	}



	// 塞入数据 true:添加成功 false：失败重试其他
	bool FLV::addPacket(const ENUM_MEDIA_TYPE& type, AVPacket* packet)
	{
		
		
		switch (type)
		{
			case ENUM_MEDIA_TYPE::VIDEO: {
				av_packet_rescale_ts(packet, p_in_video_codec_centext->time_base, p_out_video_stream->time_base);
				packet->stream_index = m_video_out_index;
				if (b_first_add_packet)
				{
					b_first_add_packet = false;
					m_stream_start_time = packet->pts;

				}

				// 这里本来就按时间基换算的所以不用在按时间基去处理时间了
				if (packet->dts != AV_NOPTS_VALUE)
					packet->dts += -m_stream_start_time;
				if (packet->pts != AV_NOPTS_VALUE)
					packet->pts += -m_stream_start_time;

				// 
				//StreamMuxingBase::log_packet(p_out_formatctx, packet, "视频");
				int ret = av_interleaved_write_frame(p_out_formatctx, packet);
				if (ret < 0)
				{
					std::cout << "视频压入FLV包失败" << std::endl;
					return false;
				}
			
				
			}; break;
			case ENUM_MEDIA_TYPE::AUDIO: {
				av_packet_rescale_ts(packet, p_in_audio_codec_centext->time_base, p_out_audio_stream->time_base);
				packet->stream_index = m_audio_out_index;
				if (b_first_add_packet)
				{
					b_first_add_packet = false;
					m_stream_start_time = packet->pts;

				}

				if (packet->dts != AV_NOPTS_VALUE)
					packet->dts += -m_stream_start_time;
				if (packet->pts != AV_NOPTS_VALUE)
					packet->pts += -m_stream_start_time;

				//StreamMuxingBase::log_packet(p_out_formatctx, packet, "音频");
				int ret = av_interleaved_write_frame(p_out_formatctx, packet);
				if (ret < 0)
				{
					std::cout << "音频压入FLV包失败" << std::endl;
					return false;
				}
			
				
			}; break;
			default:
				return false;
				break;
		}
		//av_interleaved_write_frame(p_out_formatctx, NULL);
		

		return true;
	}

	// 解析出脚本所有的数据
	/*
	bool FLV::paserScript(const uint8_t* data, const int buf_size)
	{
		// 解析包头
		const int CONST_SCRIPT_MIN_LEN = 17;
		// 最小包头等于  flv头(9) + 4字节长度 + script + len  = 17
		if (buf_size < CONST_SCRIPT_MIN_LEN)
		{
			return false;
		}

		// 先校验头
		if (data[0] != 0x46 || data[1] != 0x4c || data[2] != 0x56)
		{
			return false;
		}

		if (data[13] != 0x12)
		{
			return false;
		}
		// 算出脚本的长度
		int script_len = (data[14] << 16) + (data[15] << 8) + data[16];
		const int flv_head_len = CONST_SCRIPT_MIN_LEN + 7 + script_len + 4;
		// 判断一下flvhead头是否超限制
		if (buf_size < flv_head_len)
		{
			return false;
		}

		// script_check_len 校验长度
		int script_check_len = (data[flv_head_len - 4] << 24) + (data[flv_head_len - 3] << 16) + (data[flv_head_len - 2] << 8) + data[flv_head_len - 1];
		if (script_check_len  != script_len + 11)
		{
			return false;
		}

		//p_file->write(data, flv_head_len);

		std::shared_ptr<StreamPacket> flv_head(new StreamPacket(data, flv_head_len));
		m_flv_head = flv_head;
		return true;
	}*/

	bool FLV::paserFirstAudioPacket(const uint8_t* data, const int buf_size)
	{
		//std::cout << "送入的字节数" << buf_size << std::endl;
		// 解析的位置
		int paser_index = 0;
		while (buf_size > paser_index)
		{
			// 防止解析head越界
			if (paser_index + 11 > buf_size)
			{
				return false;
			}
			int type = data[paser_index];
			// 记录一下解析位置
			int type_index = paser_index;
		
			int script_len = (data[paser_index+1] << 16) + (data[paser_index+2] << 8) + data[paser_index+3];
			// 解析完长度向后偏移4字节
			paser_index += 4;

			//// 全0
			//bool all_zero = true;
			//// 判断连续的7字节是00
			//int paser_count = 0;
			//while (paser_count < 7)
			//{
			//	if (data[paser_index + paser_count] != 0x00)
			//	{
			//		all_zero = false;
			//		break;
			//	}
			//	paser_count++;
			//}
			// 偏移7字节
			paser_index += 7 ;
			// 偏移date
			paser_index += script_len;
			if (paser_index > buf_size)
			{
				return false;
			}
			// script_check_len 校验长度
			int script_check_len = (data[paser_index] << 24) + (data[paser_index+1] << 16) + (data[paser_index+ 2] << 8) + data[paser_index+ 3];
			if (script_check_len != script_len + 11)
			{
				return false;
			}
			// 偏移校验位
			paser_index += 4;



			// 首帧是音频
			if (0x08 == type)
			{
				Log::printInfo("flv找到音频空包了开始处理数据");
				m_flv_head->pushData(data + type_index, paser_index - type_index);
				return true;
			}

		}
		return false;
	}

	bool FLV::getNeedRestart()
	{
		if (m_audio_first_data_count > 100)
		{
			return true;
		}
		return false;
	}


	bool FLV::streamOut2Memory(uint8_t* buf, int buf_size)
	{
		
		/*for (int i = 0; i < buf_size; i++)
		{
			std::cout << std::hex << (int)buf[i] << "  ";
		}
		std::cout << std::endl << std::endl;*/

		//file->write(buf, buf_size);
		
		// 这是head
		if (b_is_first)
		{
			// 除了头之外
			std::shared_ptr<StreamPacket> flv_head(new StreamPacket(buf, buf_size));
			m_flv_head = flv_head;
			b_is_first = false;
		}
		else
		{
			/*for (int i = 0; i < buf_size; i++)
			{
				std::cout << std::hex << (int)buf[i] << "  ";
			}
			std::cout << std::endl << std::endl;*/

			if (!b_find_first_audio_data)
			{
				// 除了头之外还要把音频第一帧空包找到打进去 不要问问就是需要 不打浏览器播不了
				b_find_first_audio_data = this->paserFirstAudioPacket(buf, buf_size);
				if (b_find_first_audio_data)
				{
					m_audio_first_data_count = 0;
				}
				else
				{
					m_audio_first_data_count++;
				}
			}
			else
			{
				auto flv_mq = m_flv_param.getMQ();
				if (flv_mq != nullptr)
				{
					std::string flv_index = m_flv_param.getIndex();
					// 打包协议序列化插入
					FLVSerialize flv_serialize(m_flv_head, flv_index, buf, buf_size);
					flv_mq->pushBack(flv_serialize.getStreamPacket());
				}
			}
		}

		return true;
	}

	FLV::~FLV()
	{
		
	}




}
